/**
  ******************************************************************************
  * @file    Project/MT031x_StdPeriph_Templates/main.c 
  * @author  XXXXXXXX Software Team 
  * @version V1.0.0
  * @date    11/01/2015
  * @brief   Main program body
  ******************************************************************************
  * @attention
  *
  * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
  * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
  * TIME. AS A RESULT, XXXXXXXX SHALL NOT BE HELD LIABLE FOR ANY
  * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
  * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
  * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
  *
  * <h2><center>&copy; COPYRIGHT 2015 XXXXXXXX</center></h2>
  ******************************************************************************
  */  

/* Includes ------------------------------------------------------------------*/
// #include "main.h"
#include <stdio.h>
#include <time.h>
// #include "IO.h"
#include "Debug.h"
// #include "BSP_Uart.h"
// #include "BSP_RS485.h"

/** @addtogroup MT031x_StdPeriph_Templates
  * @{
  */

/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
#define USART0_CLOCK_DIV	1

/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
/* Private function prototypes -----------------------------------------------*/
#ifdef __GNUC__
  /* With GCC/RAISONANCE, small printf (option LD Linker->Libraries->Small printf
     set to 'Yes') calls __io_putchar() */
  #define PUTCHAR_PROTOTYPE int __io_putchar(int ch)
#else
  #define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
#endif /* __GNUC__ */

/**
  * @brief  Configuare USART.
  * @param  None
  * @retval None
  */
void DebugInit(void)						  
{
#ifndef NDEBUG
	// BSP_Uart_Init();
	//BSP_RS485_Init();
	//BSP_RS485_SetDir(RS485_DIR_OUT);
#endif 
}

#define SEGGER_RTT_FreeRTOS_PRINTF_BUFFER_SIZE	1024
//#define LOG_USE_MALLOC

#ifndef LOG_USE_MALLOC
static char sprint_buf[SEGGER_RTT_FreeRTOS_PRINTF_BUFFER_SIZE];
#endif

int SEGGER_RTT_FreeRTOS_printf(unsigned BufferIndex, const char * sFormat, ...)
{
	va_list args;
	int n;
	vTaskSuspendAll();
	#ifdef LOG_USE_MALLOC
	char *sprint_buf = pvPortMalloc(SEGGER_RTT_FreeRTOS_PRINTF_BUFFER_SIZE);
	if(sprint_buf == NULL)goto exit;
	#endif
	va_start(args, sFormat);
	n = vsnprintf(sprint_buf, SEGGER_RTT_FreeRTOS_PRINTF_BUFFER_SIZE, sFormat, args);
	va_end(args);
	SEGGER_RTT_Write(0, sprint_buf, n);
	#ifdef LOG_USE_MALLOC
	vPortFree(sprint_buf);
	exit:
	#endif
	xTaskResumeAll();
	return n;
}

#ifndef NDEBUG

void log_buff_print(const char *str, const void *buf, uint32_t len, uint8_t line, const char *fun)
{
	vTaskSuspendAll();
	 if(str)LOG("\033[%d;%dm" "%s:  %s(%u):", 
	 	LOG_BC_BLACK, LOG_FC_WHITE, fun, str, len);
	
	if(str && line != 0)LOG("\r\n");
	for(uint32_t i=0;i<len;i++){
		if(i != 0 && line != 0 && !(i%line))LOG("\r\n");
		LOG(" %02X", ((uint8_t *)buf)[i]);
	}
	LOG("\r\n");
	xTaskResumeAll();
}

log_time_t *log_time_get(void)
{
	// uint32_t timestamp = BSP_Clock_Now() + (8 * 60 * 60);
	// struct tm *_t = localtime(&timestamp);
	static log_time_t t = {0};
	// t.y 	= _t->tm_year + 1900;
	// t._m 	= _t->tm_mon + 1;
	// t.d   = _t->tm_mday;
	// t.h		= _t->tm_hour;
	// t.m		= _t->tm_min;
	// t.s		= _t->tm_sec;
	return &t;
}

#endif

/**
  * @brief  Retargets the C library printf function to the USART.
  * @param  None
  * @retval None
  */
PUTCHAR_PROTOTYPE
{

	// BSP_Uart0_Send((uint8_t)ch);
	
	return ch;
}
#if 1
// #pragma import(__use_no_semihosting)

// struct __FILE
// {
//  int handle;
// };

//FILE __stdin;
//FILE __stdout;

//void _sys_open(const char * sName, int OpenMode) {
//  (void)OpenMode;
//  
//  return ;  // Not implemented
//}

void _sys_exit(int x)
{
  x = x;
}

void _ttywrch(int c) 
{
  c = c;
}


/*int fputc(int ch, FILE *f)
{
 return (ch);
}*/

int fgetc(FILE *f)
{
 return (int)-1;
}
#endif

#ifdef  USE_FULL_ASSERT

/**
  * @brief  Reports the name of the source file and the source line number
  *   where the assert_param error has occurred.
  * @param  file: pointer to the source file name
  * @param  line: assert_param error line source number
  * @retval None
  */
void assert_failed(uint8_t* file, uint32_t line)
{ 
	/* User can add his own implementation to report the file name and line number,
	 ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
	printf("Wrong parameters value: file %s on line %d\r\n", file, line);

	/* Infinite loop */
	while (1)
	{
	}
}
#endif

